'''
Author: 码上talk|RC
Date: 2020-09-11 15:29:58
LastEditTime: 2020-09-21 18:21:20
LastEditors: 码上talk|RC
Description: 
FilePath: /charis-api/utils/gps_util.py
微信:  13680065830
邮箱:  3189482282@qq.com
oops: Just do what I think it is right
'''
import math
from sympy import *
from math import radians, cos, sin, asin, sqrt, pi


class GpsUtil():
    def __init__(self):
        self.R = 6371 * 1000
        pass

    def geodistance(self, lng1, lat1, lng2, lat2):
        lng1, lat1, lng2, lat2 = map(
            radians, [float(lng1), float(lat1), float(lng2), float(lat2)])
        dlon = lng2 - lng1
        dlat = lat2 - lat1
        a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
        distance = 2 * asin(sqrt(a)) * self.R
        distance = round(distance, 3)
        return distance

    def get_new_lat(self, lng1, lat1, dist=500):
        lat2 = 180 * dist / (self.R * pi) + lat1
        return (lng1, lat2)

    def get_new_lng(self, lng1, lat1, dist=500):
        lng2 = 180 * dist / (self.R * pi * cos(radians(lat1))) + lng1
        return (lng2, lat1)

    def get_new_lng_angle(self, lng1, lat1, dist=500, angle=30):
        lat2 = 180 * dist*sin(radians(angle)) / (self.R * pi) + lat1
        lng2 = 180 * dist*cos(radians(angle)) / \
            (self.R * pi * cos(radians(lat1))) + lng1
        return (lng2, lat2)

    def is_in_polygon(self, lng, lat, polygon):
        in_count = 0
        if len(polygon) < 3:
            return False
        for index, p in enumerate(polygon):
            lng1 = p['lng']
            lat1 = p['lat']
            if index == len(polygon) - 1:
                lng2 = polygon[0]['lng']
                lat2 = polygon[0]['lat']
            else:
                lng2 = polygon[index + 1]['lng']
                lat2 = polygon[index + 1]['lat']
            if (lat >= lat1 and lat < lat2) or (lat >= lat2 and lat < lat1):
                if abs(lat1 - lat2) > 0:
                    p_lng = lng1 - ((lng1 - lng2) *
                                    (lat1 - lat)) / (lat1 - lat2)
                    if p_lng < lng:
                        in_count += 1
        if in_count % 2 != 0:
            return True
        return False

    def bd2amap(self, lng, lat):
        PI = 3.14159265358979324 * 3000.0 / 180.0
        x = lng - 0.0065
        y = lat - 0.006
        z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * PI)
        theta = math.atan2(y, x) - 0.000003 * math.cos(x * PI)
        lng = z * math.cos(theta)
        lat = z * math.sin(theta)
        return lng, lat
